//
//  UIControl+STActionBlocks.m
//  STFramework
//
//  Created by jerry on 2019/5/2.
//  Copyright © 2019 jerry. All rights reserved.
//

#import "UIControl+STActionBlocks.h"
#import <objc/runtime.h>

static const void *UIControlSTActionBlockArray = &UIControlSTActionBlockArray;

@implementation UIControlSTActionBlockWrapper

- (void)st_invokeBlock:(id)sender {
    if (self.st_actionBlock) {
        self.st_actionBlock(sender);
    }
}
@end

@implementation UIControl (STActionBlocks)

-(void)st_handleControlEvents:(UIControlEvents)controlEvents withBlock:(UIControlSTActionBlock)actionBlock {
    NSMutableArray *actionBlocksArray = [self st_actionBlocksArray];
    
    UIControlSTActionBlockWrapper *blockActionWrapper = [[UIControlSTActionBlockWrapper alloc] init];
    blockActionWrapper.st_actionBlock = actionBlock;
    blockActionWrapper.st_controlEvents = controlEvents;
    [actionBlocksArray addObject:blockActionWrapper];
    
    [self addTarget:blockActionWrapper action:@selector(st_invokeBlock:) forControlEvents:controlEvents];
}


- (void)st_removeActionBlocksForControlEvents:(UIControlEvents)controlEvents {
    NSMutableArray *actionBlocksArray = [self st_actionBlocksArray];
    NSMutableArray *wrappersToRemove = [NSMutableArray arrayWithCapacity:[actionBlocksArray count]];
    
    [actionBlocksArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        UIControlSTActionBlockWrapper *wrapperTmp = obj;
        if (wrapperTmp.st_controlEvents == controlEvents) {
            [wrappersToRemove addObject:wrapperTmp];
            [self removeTarget:wrapperTmp action:@selector(st_invokeBlock:) forControlEvents:controlEvents];
        }
    }];
    
    [actionBlocksArray removeObjectsInArray:wrappersToRemove];
}


- (NSMutableArray *)st_actionBlocksArray {
    NSMutableArray *actionBlocksArray = objc_getAssociatedObject(self, UIControlSTActionBlockArray);
    if (!actionBlocksArray) {
        actionBlocksArray = [NSMutableArray array];
        objc_setAssociatedObject(self, UIControlSTActionBlockArray, actionBlocksArray, OBJC_ASSOCIATION_RETAIN);
    }
    return actionBlocksArray;
}
@end
